Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

64장. Read Replica — 읽기를 어떻게 늘릴까

이 장에서 말하고자 하는 것

Multi-AZ는 장애 대비를 해준다.
하지만 읽기 트래픽이 늘어나는 문제는 풀어주지 않는다.

사용자 늘어남
  → 읽기 쿼리 폭증
  → Primary DB CPU 100%

이때 등장하는 게

Read Replica

다.


1. Read Replica의 구조

[Primary]   ← 쓰기
   ↓ 비동기 복제
[Replica 1]   ← 읽기
[Replica 2]   ← 읽기
[Replica 3]   ← 읽기
  • 쓰기는 Primary로
  • 읽기는 Primary 또는 Replica로 분산

복제는 비동기 다.
Multi-AZ Standby가 동기인 것과 결정적으로 다르다.


2. Replication Lag — 약간의 지연

비동기 복제이므로 Replica는

항상 Primary보다 약간 뒤처질 수 있다

지연은 보통 수십 ms ~ 수 초 정도.

1. 사용자가 주문을 만든다 (Primary에 INSERT)
2. 곧장 "내 주문 목록" 요청 (Replica에서 SELECT)
3. Replica에 아직 반영 안 됨 → 새 주문이 안 보임

이 한 줄짜리 시나리오가 운영에서 자주 만난다.


3. 어떻게 다루는가

1. 강한 일관성이 필요한 읽기는 Primary로

주문 직후 사용자에게 보여줄 데이터 → Primary
대시보드 / 통계 / 검색 → Replica

2. 같은 트랜잭션 안에서는 같은 노드

쓰기 직후 같은 트랜잭션의 후속 읽기는 Primary로.

3. “내 데이터” 는 Primary로

자기가 방금 만든 데이터를 즉시 봐야 하는 화면은 Primary.


4. Read Replica 활용 패턴

패턴용도
대시보드 / 분석 쿼리무거운 SELECT 를 Replica로 격리
검색 / 통계약간 오래된 데이터로도 충분
Read-Heavy API다수의 Replica 로 수평 확장
다른 리전 ReplicaDR · 글로벌 응답성

5. Cross-Region Read Replica

다른 리전에도 Replica를 둘 수 있다.

[ap-northeast-2: Primary]
       ↓ 리전 간 복제
[us-east-1: Replica]

용도:

  • 글로벌 사용자에게 가까운 곳에서 읽기 응답
  • DR (장애 복구) — 리전 전체 장애에 대비

6. Replica 승격 (Promotion)

Primary에 문제가 생기면 Read Replica를 승격(promote) 해 새 Primary로 만들 수 있다.

aws rds promote-read-replica \
  --db-instance-identifier orders-replica-1

승격 후에는 더 이상 Replica가 아니다 (독립적인 DB).


7. 우리 서비스에서

[ECS "orders"]
   ↓ 쓰기·강한 읽기
[RDS Primary  (Multi-AZ)]
   ↓ 비동기 복제
[Replica 1]  ← 무거운 SELECT
[Replica 2]  ← 대시보드
  • Primary: 트랜잭션 · 강한 일관성 읽기
  • Replicas: 대시보드 · 통계 · 무거운 SELECT

읽기 쿼리가 한가하면 Replica는 0~1개로 시작.


8. 직접 확인해보기 — CLI

Read Replica 만들기

aws rds create-db-instance-read-replica \
  --db-instance-identifier orders-replica-1 \
  --source-db-instance-identifier orders \
  --db-instance-class db.t4g.small

Replication Lag 확인

aws cloudwatch get-metric-statistics \
  --namespace AWS/RDS \
  --metric-name ReplicaLag \
  --dimensions Name=DBInstanceIdentifier,Value=orders-replica-1 \
  --start-time 2026-01-01T00:00:00Z \
  --end-time   2026-01-02T00:00:00Z \
  --period 60 \
  --statistics Average

ReplicaLag 알람은 거의 항상 켠다


9. 코드로는 이렇게 생겼다 — Terraform

resource "aws_db_instance" "orders" {
  identifier     = "orders"
  engine         = "postgres"
  instance_class = "db.t4g.small"
  multi_az       = true
  # ... 62장 코드와 동일
}

resource "aws_db_instance" "orders_ro" {
  identifier             = "orders-ro-1"
  replicate_source_db    = aws_db_instance.orders.identifier
  instance_class         = "db.t4g.small"
  publicly_accessible    = false
  vpc_security_group_ids = [aws_security_group.db.id]
}

Replica는 별도 엔드포인트를 가진다.


10. 애플리케이션에서 두 엔드포인트 다루기

DATABASE_URL=postgres://...primary.../app
DATABASE_RO_URL=postgres://...replica.../app

코드에서

if (isReadOnly && !needsStrongConsistency) → DATABASE_RO_URL
else → DATABASE_URL

ORM에 따라 read/write 분리를 자동화해주는 기능이 있다.


11. 이렇게 쓰면 망한다 — 안티패턴

안티패턴 1. 강한 일관성이 필요한 읽기를 Replica로 보낸다

“방금 만든 데이터가 안 보이는” 버그가 난다.

안티패턴 2. ReplicaLag 알람을 안 건다

복제가 끊겼는데도 모른다 → Replica에서 옛 데이터만 응답.

안티패턴 3. Replica 한 대로 모든 읽기를 받는다

Replica가 죽으면 즉시 부하가 Primary로 몰린다.

운영 부하가 크다면 Replica도 2대 이상

안티패턴 4. Replica를 영원한 DR 백업으로만 둔다

DR이 목적이라면 Cross-Region Replica + 정기 페일오버 시험이 필요하다.
승격 절차를 한 번도 안 해봤다면 실전에서 실패한다.


12. 한 줄로 정리

Read Replica는 비동기 복제 기반으로 읽기 부하를 분산하는 도구이며,
강한 일관성이 필요한 읽기와 그렇지 않은 읽기를 구분하는 게 핵심이다


13. 이 장의 핵심 정리

  1. Read Replica는 비동기 복제 기반의 읽기 전용 DB다.
  2. Multi-AZ Standby와는 다르다 — Standby는 트래픽을 안 받는다.
  3. Replication Lag 때문에 강한 일관성 읽기는 Primary로 보낸다.
  4. Cross-Region Replica로 글로벌 응답성과 DR을 동시에 다룰 수 있다.
  5. ReplicaLag 알람은 거의 항상 켠다.
  6. 승격 절차는 사전에 시뮬레이션해 둔다.